---
title: Syntax Comparison Basics
---

This module explores the fundamental syntax differences between JavaScript and Go, covering variable declarations, control flow, functions, data types, and other core language constructs.

## Variable Declaration and Type System

JavaScript uses dynamic typing where variable types are determined at runtime, while Go uses static typing with type inference capabilities.

### Variable Declaration Methods Comparison

| Declaration Method | JavaScript | Go | Description |
| :----------------- | :---------- | :-- | :----------- |
| **Variable Declaration** | `let x = 10;` | `x := 10` | Type inference, local scope |
| **Constant Declaration** | `const x = 10;` | `const x = 10` | Cannot be reassigned |
| **Explicit Type Declaration** | `let x: number = 10;` (TypeScript) | `var x int = 10` | Explicitly specify type |
| **Zero Value Initialization** | `let x;` (undefined) | `var x int` (0) | Default value initialization |
| **Multiple Assignment** | `let a = 1, b = 2;` | `a, b := 1, 2` | Declare multiple variables simultaneously |
| **Block Scope** | `{ let x = 10; }` | `{ x := 10 }` | Limit variable scope |
| **Function Scope** | `var x = 10;` | `var x = 10` | Hoisted to function top |

### Type Inference Comparison

| Feature | JavaScript | Go | Description |
| :------- | :---------- | :-- | :----------- |
| **Numeric Types** | `number` (64-bit float) | `int`, `int8`, `int16`, `int32`, `int64`, `uint`, `float32`, `float64` | Go has precise integer types |
| **String Types** | `string` | `string` | Both support UTF-8 |
| **Boolean Types** | `boolean` | `bool` | Same concept |
| **Array Types** | `Array` (dynamic) | `[n]T` (fixed), `[]T` (slice) | Go distinguishes arrays and slices |
| **Object Types** | `Object` | `struct`, `map` | Go uses structs as primary data structure |
| **Null Values** | `null`, `undefined` | `nil` | Go uses nil uniformly |
| **Type Checking** | Runtime | Compile time | Go provides compile-time type safety |

<UniversalEditor title="Variable Declaration and Assignment Comparison" compare={true}>
```javascript !! js
// JavaScript: Dynamic Typing
let age = 30; // Number
let name = "Alice"; // String
let isActive = true; // Boolean
let scores = [85, 92, 78]; // Array
let person = { name: "Bob", age: 25 }; // Object

console.log(typeof age); // "number"
console.log(typeof name); // "string"
console.log(Array.isArray(scores)); // true
```

```go !! go
// Go: Static Typing with Type Inference
package main

import "fmt"

func main() {
    age := 30 // int (type inferred)
    name := "Alice" // string (type inferred)
    isActive := true // bool (type inferred)
    scores := []int{85, 92, 78} // slice of int
    person := map[string]interface{}{"name": "Bob", "age": 25} // map
    
    // Go doesn't have typeof like JavaScript, but you can use reflection
    fmt.Printf("age type: %T\n", age) // int
    fmt.Printf("name type: %T\n", name) // string
    fmt.Printf("scores type: %T\n", scores) // []int
}
```
</UniversalEditor>

## Control Flow Statements Comparison

Both languages support similar control flow structures, but with different syntax and conventions.

### If/Else Statements

<UniversalEditor title="If/Else Comparison" compare={true}>
```javascript !! js
// JavaScript: If/Else
let temperature = 25;

if (temperature > 30) {
    console.log("It's hot!");
} else if (temperature > 20) {
    console.log("It's warm.");
} else {
    console.log("It's cold.");
}

// JavaScript allows truthy/falsy values
if (temperature) {
    console.log("Temperature is truthy");
}
```

```go !! go
// Go: If/Else
package main

import "fmt"

func main() {
    temperature := 25

    if temperature > 30 {
        fmt.Println("It's hot!")
    } else if temperature > 20 {
        fmt.Println("It's warm.")
    } else {
        fmt.Println("It's cold.")
    }

    // Go requires explicit boolean expressions
    if temperature > 0 {
        fmt.Println("Temperature is positive")
    }
}
```
</UniversalEditor>

### For Loops

<UniversalEditor title="For Loop Comparison" compare={true}>
```javascript !! js
// JavaScript: For Loops
// Traditional for loop
for (let i = 0; i < 5; i++) {
    console.log(i);
}

// For...of (for iterables)
let arr = [1, 2, 3, 4, 5];
for (let val of arr) {
    console.log(val);
}

// For...in (for object properties)
let obj = { a: 1, b: 2, c: 3 };
for (let key in obj) {
    console.log(key, obj[key]);
}

// forEach method
arr.forEach((val, index) => {
    console.log(`Index ${index}: ${val}`);
});
```

```go !! go
// Go: For Loops
package main

import "fmt"

func main() {
    // Traditional for loop (Go's only loop construct)
    for i := 0; i < 5; i++ {
        fmt.Println(i)
    }

    // Range-based for loop (similar to for...of)
    arr := []int{1, 2, 3, 4, 5}
    for i, val := range arr {
        fmt.Printf("Index %d: %d\n", i, val)
    }

    // Range over map (similar to for...in)
    obj := map[string]int{"a": 1, "b": 2, "c": 3}
    for key, val := range obj {
        fmt.Printf("%s: %d\n", key, val)
    }

    // Range over slice (index only)
    for i := range arr {
        fmt.Printf("Index: %d\n", i)
    }

    // Range over slice (value only)
    for _, val := range arr {
        fmt.Printf("Value: %d\n", val)
    }
}
```
</UniversalEditor>

## Function Definition and Calling

Go functions require explicit return types and have different syntax compared to JavaScript functions.

<UniversalEditor title="Function Definition Comparison" compare={true}>
```javascript !! js
// JavaScript: Function Definitions
// Function declaration
function greet(name) {
    return `Hello, ${name}!`;
}

// Function expression
const add = function(a, b) {
    return a + b;
};

// Arrow function
const multiply = (a, b) => a * b;

// Function with default parameters
function greetWithDefault(name = "World") {
    return `Hello, ${name}!`;
}

// Function with rest parameters
function sum(...numbers) {
    return numbers.reduce((acc, num) => acc + num, 0);
}

console.log(greet("Bob"));
console.log(add(5, 3));
console.log(multiply(4, 6));
console.log(greetWithDefault());
console.log(sum(1, 2, 3, 4, 5));
```

```go !! go
// Go: Function Definitions
package main

import "fmt"

// Function declaration
func greet(name string) string {
    return fmt.Sprintf("Hello, %s!", name)
}

// Function with multiple return values
func divide(a, b float64) (float64, error) {
    if b == 0 {
        return 0, fmt.Errorf("division by zero")
    }
    return a / b, nil
}

// Function with named return values
func multiply(a, b int) (result int) {
    result = a * b
    return // naked return
}

// Function with variadic parameters (similar to rest parameters)
func sum(numbers ...int) int {
    total := 0
    for _, num := range numbers {
        total += num
    }
    return total
}

// Function as a variable (similar to function expression)
var add = func(a, b int) int {
    return a + b
}

func main() {
    fmt.Println(greet("Bob"))
    
    result, err := divide(10, 2)
    if err != nil {
        fmt.Println("Error:", err)
    } else {
        fmt.Println("Result:", result)
    }
    
    fmt.Println(multiply(4, 6))
    fmt.Println(sum(1, 2, 3, 4, 5))
    fmt.Println(add(5, 3))
}
```
</UniversalEditor>

## Data Types and Structures

Go has a rich set of built-in types and structures that differ significantly from JavaScript.

### Detailed Data Types Comparison

| Data Type | JavaScript | Go | Zero Value | Description |
| :-------- | :---------- | :-- | :---------- | :----------- |
| **Integer** | `number` | `int`, `int8`, `int16`, `int32`, `int64` | `0` | Go has precise integer sizes |
| **Unsigned Integer** | None | `uint`, `uint8`, `uint16`, `uint32`, `uint64` | `0` | Go supports unsigned integers |
| **Float** | `number` | `float32`, `float64` | `0.0` | Go distinguishes single/double precision |
| **Complex** | None | `complex64`, `complex128` | `0+0i` | Go has built-in complex number support |
| **String** | `string` | `string` | `""` | Both support UTF-8 encoding |
| **Boolean** | `boolean` | `bool` | `false` | Same concept |
| **Null Value** | `null`, `undefined` | `nil` | `nil` | Go uses nil uniformly |
| **Array** | `Array` | `[n]T` | `[0,0,0]` | Go arrays have fixed size |
| **Dynamic Array** | `Array` | `[]T` (slice) | `nil` | Go slices are dynamic |
| **Object** | `Object` | `struct` | Struct zero value | Go structs have defined structure |
| **Map** | `Map` | `map[K]V` | `nil` | Key-value storage |
| **Set** | `Set` | No built-in | - | Can be simulated with map in Go |
| **Function** | `Function` | `func` | `nil` | Function type |
| **Channel** | None | `chan T` | `nil` | Go concurrent communication |
| **Interface** | None | `interface{}` | `nil` | Go polymorphism support |
| **Pointer** | None | `*T` | `nil` | Go memory address reference |

<UniversalEditor title="Data Types Comparison" compare={true}>
```javascript !! js
// JavaScript: Data Types and Structures
// Primitive types
let number = 42;
let string = "Hello";
let boolean = true;
let nullValue = null;
let undefinedValue = undefined;

// Arrays
let array = [1, 2, 3, 4, 5];
let mixedArray = [1, "hello", true, null];

// Objects
let object = {
    name: "Alice",
    age: 30,
    isActive: true
};

// Maps (ES6)
let map = new Map();
map.set("key1", "value1");
map.set("key2", "value2");

// Sets (ES6)
let set = new Set([1, 2, 3, 3, 4]); // duplicates are removed

console.log(array.length);
console.log(Object.keys(object));
console.log(map.get("key1"));
console.log(set.has(3));
```

```go !! go
// Go: Data Types and Structures
package main

import "fmt"

func main() {
    // Basic types
    var number int = 42
    var text string = "Hello"
    var boolean bool = true
    
    // Arrays (fixed size)
    var array [5]int = [5]int{1, 2, 3, 4, 5}
    var mixedArray [4]interface{} = [4]interface{}{1, "hello", true, nil}
    
    // Slices (dynamic arrays)
    slice := []int{1, 2, 3, 4, 5}
    slice = append(slice, 6) // add element
    
    // Maps
    object := map[string]interface{}{
        "name":     "Alice",
        "age":      30,
        "isActive": true,
    }
    
    // Structs (similar to objects but with defined structure)
    type Person struct {
        Name     string
        Age      int
        IsActive bool
    }
    
    person := Person{
        Name:     "Bob",
        Age:      25,
        IsActive: true,
    }
    
    fmt.Printf("Array length: %d\n", len(array))
    fmt.Printf("Slice length: %d\n", len(slice))
    fmt.Printf("Map keys: %v\n", getMapKeys(object))
    fmt.Printf("Person: %+v\n", person)
}

// Helper function to get map keys
func getMapKeys(m map[string]interface{}) []string {
    keys := make([]string, 0, len(m))
    for k := range m {
        keys = append(keys, k)
    }
    return keys
}
```
</UniversalEditor>

## Scope and Lifetime

Both languages have block scope, but Go's scoping rules are more explicit and consistent.

<UniversalEditor title="Scope and Lifetime Comparison" compare={true}>
```javascript !! js
// JavaScript: Scope and Hoisting
function example() {
    let x = 10; // block-scoped
    
    if (true) {
        let y = 20; // block-scoped
        var z = 30; // function-scoped (hoisted)
        console.log(x); // 10
        console.log(y); // 20
        console.log(z); // 30
    }
    
    console.log(x); // 10
    console.log(z); // 30 (accessible due to hoisting)
    // console.log(y); // ReferenceError: y is not defined
}

// Closures
function createCounter() {
    let count = 0;
    return function() {
        count++;
        return count;
    };
}

const counter = createCounter();
console.log(counter()); // 1
console.log(counter()); // 2
```

```go !! go
// Go: Scope and Lifetime
package main

import "fmt"

func example() {
    x := 10 // function-scoped
    
    if true {
        y := 20 // block-scoped
        fmt.Println(x) // 10
        fmt.Println(y) // 20
    }
    
    fmt.Println(x) // 10
    // fmt.Println(y) // Error: undefined: y
}

// Closures in Go
func createCounter() func() int {
    count := 0
    return func() int {
        count++
        return count
    }
}

func main() {
    example()
    
    counter := createCounter()
    fmt.Println(counter()) // 1
    fmt.Println(counter()) // 2
}
```
</UniversalEditor>

## Error Handling

JavaScript uses try-catch for exception handling, while Go uses explicit error return values.

<UniversalEditor title="Error Handling Comparison" compare={true}>
```javascript !! js
// JavaScript: Exception Handling
function divide(a, b) {
    if (b === 0) {
        throw new Error("Division by zero");
    }
    return a / b;
}

function safeDivide(a, b) {
    try {
        const result = divide(a, b);
        console.log("Result:", result);
        return result;
    } catch (error) {
        console.error("Error:", error.message);
        return null;
    }
}

// Async error handling
async function fetchData() {
    try {
        const response = await fetch('https://api.example.com/data');
        if (!response.ok) {
            throw new Error(`HTTP error! status: ${response.status}`);
        }
        const data = await response.json();
        return data;
    } catch (error) {
        console.error("Fetch error:", error.message);
        throw error; // re-throw
    }
}

safeDivide(10, 2); // Result: 5
safeDivide(10, 0); // Error: Division by zero
```

```go !! go
// Go: Error Handling
package main

import (
    "errors"
    "fmt"
    "net/http"
    "io/ioutil"
)

// Function that returns an error
func divide(a, b float64) (float64, error) {
    if b == 0 {
        return 0, errors.New("division by zero")
    }
    return a / b, nil
}

// Function that handles errors
func safeDivide(a, b float64) {
    result, err := divide(a, b)
    if err != nil {
        fmt.Printf("Error: %v\n", err)
        return
    }
    fmt.Printf("Result: %v\n", result)
}

// Custom error type
type ValidationError struct {
    Field string
    Message string
}

func (e ValidationError) Error() string {
    return fmt.Sprintf("validation error in %s: %s", e.Field, e.Message)
}

// Function with custom error
func validateAge(age int) error {
    if age < 0 {
        return ValidationError{Field: "age", Message: "age cannot be negative"}
    }
    if age > 150 {
        return ValidationError{Field: "age", Message: "age seems unrealistic"}
    }
    return nil
}

// HTTP request with error handling
func fetchData(url string) ([]byte, error) {
    resp, err := http.Get(url)
    if err != nil {
        return nil, fmt.Errorf("failed to fetch data: %w", err)
    }
    defer resp.Body.Close()
    
    if resp.StatusCode != http.StatusOK {
        return nil, fmt.Errorf("HTTP error! status: %d", resp.StatusCode)
    }
    
    body, err := ioutil.ReadAll(resp.Body)
    if err != nil {
        return nil, fmt.Errorf("failed to read response: %w", err)
    }
    
    return body, nil
}

func main() {
    safeDivide(10, 2) // Result: 5
    safeDivide(10, 0) // Error: division by zero
    
    if err := validateAge(-5); err != nil {
        fmt.Printf("Validation error: %v\n", err)
    }
    
    if err := validateAge(200); err != nil {
        fmt.Printf("Validation error: %v\n", err)
    }
}
```
</UniversalEditor>

## Variable Scope Comparison

JavaScript and Go have some important differences in variable scope.

### Scope Rules Comparison

| Scope Type | JavaScript | Go | Description |
| :--------- | :---------- | :-- | :----------- |
| **Global Scope** | `var x = 10;` | `var x = 10` (package level) | Both support global variables |
| **Function Scope** | `function() { var x = 10; }` | `func() { x := 10 }` | Variables inside functions |
| **Block Scope** | `{ let x = 10; }` | `{ x := 10 }` | Variables within braces |
| **Hoisting Behavior** | `var` hoisted to function top | No hoisting | Go variables must be declared before use |
| **Closure Support** | Fully supported | Fully supported | Both support function closures |
| **Variable Shadowing** | Supported | Supported | Inner variables shadow outer ones |
| **Loop Variables** | `for (let i = 0; ...)` | `for i := 0; ...` | Loop counter scope |

### Variable Lifetime Comparison

| Lifetime Feature | JavaScript | Go | Description |
| :--------------- | :---------- | :-- | :----------- |
| **Garbage Collection** | Automatic | Automatic | Both use garbage collection |
| **Memory Management** | Automatic | Automatic | Developers don't need manual management |
| **Variable Destruction** | At scope end | At scope end | Automatic cleanup |
| **Reference Counting** | Automatic | Automatic | Reference counting management |
| **Memory Leaks** | Closures may cause | Closures may cause | Need to watch for circular references |

## Basic Data Type Comparison

Go has a comprehensive set of built-in types with specific purposes.

| JavaScript Type | Go Equivalent(s) | Notes |
| :-------------- | :--------------- | :---- |
| `number`        | `int`, `int8`, `int16`, `int32`, `int64`, `uint`, `uint8`, `uint16`, `uint32`, `uint64`, `float32`, `float64`, `complex64`, `complex128` | Go has specific integer sizes |
| `string`        | `string` | UTF-8 encoded by default |
| `boolean`       | `bool` | Same concept |
| `null`          | `nil` | Used for pointers, interfaces, slices, maps, channels |
| `undefined`     | No direct equivalent | Often represented by `nil` or zero values |
| `object`        | `struct`, `map[string]interface{}` | Structs are the primary way to group data |
| `array`         | `[n]T` (array), `[]T` (slice) | Arrays are fixed-size, slices are dynamic |
| `symbol`        | No direct equivalent | Not needed in Go's type system |
| `bigint`        | `int64`, `uint64`, or external packages | For arbitrary precision |

## Operators and Expressions

Most operators are similar, but Go has some differences in syntax and behavior.

<UniversalEditor title="Operators Comparison" compare={true}>
```javascript !! js
// JavaScript: Operators
let a = 10, b = 3;

// Arithmetic
let sum = a + b; // 13
let difference = a - b; // 7
let product = a * b; // 30
let quotient = a / b; // 3.333...
let remainder = a % b; // 1
let power = a ** b; // 1000

// Comparison
let isEqual = (a === b); // false (strict equality)
let isLooseEqual = (a == b); // false (loose equality)
let isGreater = (a > b); // true
let isLess = (a < b); // false

// Logical
let and = true && false; // false
let or = true || false; // true
let not = !true; // false

// Bitwise
let bitwiseAnd = a & b; // 2
let bitwiseOr = a | b; // 11
let bitwiseXor = a ^ b; // 9
let leftShift = a << 1; // 20
let rightShift = a >> 1; // 5

console.log(sum, difference, product, quotient, remainder, power);
```

```go !! go
// Go: Operators
package main

import (
    "fmt"
    "math"
)

func main() {
    a, b := 10, 3

    // Arithmetic
    sum := a + b // 13
    difference := a - b // 7
    product := a * b // 30
    quotient := float64(a) / float64(b) // 3.333... (need float conversion)
    remainder := a % b // 1
    power := math.Pow(float64(a), float64(b)) // 1000 (need math package)

    // Comparison
    isEqual := (a == b) // false
    isGreater := (a > b) // true
    isLess := (a < b) // false

    // Logical
    and := true && false // false
    or := true || false // true
    not := !true // false

    // Bitwise
    bitwiseAnd := a & b // 2
    bitwiseOr := a | b // 11
    bitwiseXor := a ^ b // 9
    leftShift := a << 1 // 20
    rightShift := a >> 1 // 5

    fmt.Printf("Arithmetic: %d, %d, %d, %.2f, %d, %.0f\n", 
        sum, difference, product, quotient, remainder, power)
    fmt.Printf("Comparison: %t, %t, %t\n", isEqual, isGreater, isLess)
    fmt.Printf("Logical: %t, %t, %t\n", and, or, not)
    fmt.Printf("Bitwise: %d, %d, %d, %d, %d\n", 
        bitwiseAnd, bitwiseOr, bitwiseXor, leftShift, rightShift)
}
```
</UniversalEditor>

---

### Practice Questions:
1. Explain the difference between Go's `array` and `slice` types, and when you would use each.
2. Write a Go function that takes a slice of integers and returns the sum and average, demonstrating multiple return values.
3. How does Go's error handling differ from JavaScript's exception handling? Provide examples of both approaches.
4. Create a Go struct to represent a `Person` with fields for name, age, and email, then write a function to validate the person data.

### Project Idea:
* Build a simple calculator program in Go that can perform basic arithmetic operations, demonstrating function usage, error handling, and user input processing. Compare this with a JavaScript equivalent.

### Next Steps:
* Learn about Go's package system and module management
* Understand Go's type system and interfaces
* Explore Go's powerful concurrency features with goroutines and channels
